package com.property.demo.controller;

import com.property.demo.dto.ApiResponse;
import com.property.demo.model.Role;
import com.property.demo.model.User;
import com.property.demo.model.UserRole;
import com.property.demo.repository.RoleRepository;
import com.property.demo.repository.UserRepository;
import com.property.demo.repository.UserRoleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private UserRoleRepository userRoleRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @GetMapping
    public ResponseEntity<?> getAllUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String role) {
        
        logger.info("获取用户列表 - 页码: {}, 大小: {}, 用户名: {}, 角色: {}", page, size, username, role);
        
        try {
            Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending());
            Page<User> usersPage;
            
            if (username != null && !username.isEmpty() && role != null && !role.isEmpty()) {
                usersPage = userRepository.findByUsernameContainingAndRoleCode(username, role, pageable);
            } else if (username != null && !username.isEmpty()) {
                usersPage = userRepository.findByUsernameContaining(username, pageable);
            } else if (role != null && !role.isEmpty()) {
                usersPage = userRepository.findByRoleCode(role, pageable);
            } else {
                usersPage = userRepository.findAll(pageable);
            }
            
            List<User> users = usersPage.getContent();
            
            // 移除密码信息
            users.forEach(user -> user.setPassword(null));
            
            Map<String, Object> response = new HashMap<>();
            response.put("content", users);
            response.put("currentPage", usersPage.getNumber());
            response.put("totalItems", usersPage.getTotalElements());
            response.put("totalPages", usersPage.getTotalPages());
            
            logger.info("成功获取用户列表 - 总数: {}", usersPage.getTotalElements());
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取用户列表失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取用户列表失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<?> getUserById(@PathVariable Long id) {
        logger.info("获取用户详情 - ID: {}", id);
        
        try {
            Optional<User> userOpt = userRepository.findById(id);
            
            if (!userOpt.isPresent()) {
                logger.warn("未找到用户 - ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            User user = userOpt.get();
            user.setPassword(null); // 移除密码信息
            
            logger.info("成功获取用户详情 - ID: {}, 用户名: {}", id, user.getUsername());
            return ResponseEntity.ok(user);
        } catch (Exception e) {
            logger.error("获取用户详情失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取用户详情失败: " + e.getMessage()));
        }
    }
    
    @PostMapping
    public ResponseEntity<?> createUser(@RequestBody User user) {
        logger.info("创建用户 - 用户名: {}", user.getUsername());
        
        try {
            if (userRepository.existsByUsername(user.getUsername())) {
                logger.warn("创建用户失败 - 用户名已存在: {}", user.getUsername());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "用户名已被使用!"));
            }

            if (user.getEmail() != null && !user.getEmail().isEmpty() && userRepository.existsByEmail(user.getEmail())) {
                logger.warn("创建用户失败 - 邮箱已被使用: {}", user.getEmail());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "邮箱已被使用!"));
            }

            // 加密密码
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            
            User savedUser = userRepository.save(user);
            savedUser.setPassword(null); // 移除密码信息
            
            logger.info("用户创建成功 - ID: {}, 用户名: {}", savedUser.getId(), savedUser.getUsername());
            return ResponseEntity.ok(savedUser);
        } catch (Exception e) {
            logger.error("创建用户失败 - 用户名: {}, 错误: {}", user.getUsername(), e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "创建用户失败: " + e.getMessage()));
        }
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
        logger.info("更新用户 - ID: {}", id);
        
        try {
            Optional<User> userOpt = userRepository.findById(id);
            
            if (!userOpt.isPresent()) {
                logger.warn("更新用户失败 - 未找到用户 ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            User user = userOpt.get();
            
            // 检查用户名是否已被其他用户使用
            if (!user.getUsername().equals(userDetails.getUsername()) && 
                userRepository.existsByUsername(userDetails.getUsername())) {
                logger.warn("更新用户失败 - 用户名已被使用: {}", userDetails.getUsername());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "用户名已被使用!"));
            }
            
            // 检查邮箱是否已被其他用户使用
            if (userDetails.getEmail() != null && !userDetails.getEmail().isEmpty() && 
                !userDetails.getEmail().equals(user.getEmail()) && 
                userRepository.existsByEmail(userDetails.getEmail())) {
                logger.warn("更新用户失败 - 邮箱已被使用: {}", userDetails.getEmail());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "邮箱已被使用!"));
            }
            
            // 更新用户信息
            user.setUsername(userDetails.getUsername());
            user.setFullName(userDetails.getFullName());
            user.setEmail(userDetails.getEmail());
            user.setPhoneNumber(userDetails.getPhoneNumber());
            
            // 如果提供了新密码，则更新密码
            if (userDetails.getPassword() != null && !userDetails.getPassword().isEmpty()) {
                user.setPassword(passwordEncoder.encode(userDetails.getPassword()));
            }
            
            User updatedUser = userRepository.save(user);
            updatedUser.setPassword(null); // 移除密码信息
            
            logger.info("用户更新成功 - ID: {}, 用户名: {}", updatedUser.getId(), updatedUser.getUsername());
            return ResponseEntity.ok(updatedUser);
        } catch (Exception e) {
            logger.error("更新用户失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "更新用户失败: " + e.getMessage()));
        }
    }
    
    @DeleteMapping("/{id}")
    @Transactional
    public ResponseEntity<?> deleteUser(@PathVariable Long id) {
        logger.info("删除用户 - ID: {}", id);
        
        try {
            Optional<User> userOpt = userRepository.findById(id);
            
            if (!userOpt.isPresent()) {
                logger.warn("删除用户失败 - 未找到用户 ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            User user = userOpt.get();
            
            // 不允许删除admin用户
            if ("admin".equals(user.getUsername())) {
                logger.warn("删除用户失败 - 不允许删除管理员用户");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "不允许删除管理员用户!"));
            }
            
            // 删除用户角色关联
            userRoleRepository.deleteByUserId(id);
            
            // 删除用户
            userRepository.delete(user);
            
            logger.info("用户删除成功 - ID: {}, 用户名: {}", id, user.getUsername());
            return ResponseEntity.ok(new ApiResponse(true, "用户删除成功!"));
        } catch (Exception e) {
            logger.error("删除用户失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "删除用户失败: " + e.getMessage()));
        }
    }
    
    @DeleteMapping("/batch")
    @Transactional
    public ResponseEntity<?> batchDeleteUsers(@RequestBody List<Long> ids) {
        logger.info("批量删除用户 - IDs: {}", ids);
        
        try {
            // 检查是否包含admin用户
            List<User> users = userRepository.findAllById(ids);
            for (User user : users) {
                if ("admin".equals(user.getUsername())) {
                    logger.warn("批量删除用户失败 - 不允许删除管理员用户");
                    return ResponseEntity.badRequest().body(new ApiResponse(false, "不允许删除管理员用户!"));
                }
            }
            
            // 删除用户角色关联
            for (Long userId : ids) {
                userRoleRepository.deleteByUserId(userId);
            }
            
            // 删除用户
            userRepository.deleteAllById(ids);
            
            logger.info("批量删除用户成功 - 数量: {}", ids.size());
            return ResponseEntity.ok(new ApiResponse(true, "批量删除用户成功!"));
        } catch (Exception e) {
            logger.error("批量删除用户失败 - 错误: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "批量删除用户失败: " + e.getMessage()));
        }
    }
    
    @PatchMapping("/{id}/status")
    public ResponseEntity<?> updateUserStatus(@PathVariable Long id, @RequestBody Map<String, Boolean> status) {
        logger.info("更新用户状态 - ID: {}, 状态: {}", id, status.get("active"));
        
        try {
            Optional<User> userOpt = userRepository.findById(id);
            
            if (!userOpt.isPresent()) {
                logger.warn("更新用户状态失败 - 未找到用户 ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            User user = userOpt.get();
            
            // 不允许禁用admin用户
            if ("admin".equals(user.getUsername()) && !status.get("active")) {
                logger.warn("更新用户状态失败 - 不允许禁用管理员用户");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "不允许禁用管理员用户!"));
            }
            
            // 在实际项目中，您需要添加一个active字段到User实体类
            // 这里我们假设已经添加了这个字段
            // user.setActive(status.get("active"));
            
            // 由于当前实体类没有active字段，我们暂时不做实际更新
            // userRepository.save(user);
            
            logger.info("用户状态更新成功 - ID: {}, 用户名: {}, 状态: {}", id, user.getUsername(), status.get("active"));
            return ResponseEntity.ok(new ApiResponse(true, "用户状态更新成功!"));
        } catch (Exception e) {
            logger.error("更新用户状态失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "更新用户状态失败: " + e.getMessage()));
        }
    }
    
    @PostMapping("/{userId}/roles")
    @Transactional
    public ResponseEntity<?> assignRolesToUser(@PathVariable Long userId, @RequestBody Map<String, List<Long>> request) {
        logger.info("为用户分配角色 - 用户ID: {}", userId);
        
        try {
            Optional<User> userOpt = userRepository.findById(userId);
            
            if (!userOpt.isPresent()) {
                logger.warn("分配角色失败 - 未找到用户 ID: {}", userId);
                return ResponseEntity.notFound().build();
            }
            
            List<Long> roleIds = request.get("roleIds");
            if (roleIds == null) {
                logger.warn("分配角色失败 - 未提供角色ID列表");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "未提供角色ID列表!"));
            }
            
            // 先删除该用户的所有角色
            userRoleRepository.deleteByUserId(userId);
            
            // 添加新的角色
            List<UserRole> userRoles = roleIds.stream()
                .map(roleId -> {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    return userRole;
                })
                .collect(Collectors.toList());
            
            userRoleRepository.saveAll(userRoles);
            
            logger.info("为用户分配角色成功 - 用户ID: {}, 角色数量: {}", userId, roleIds.size());
            
            Map<String, Object> response = new HashMap<>();
            response.put("userId", userId);
            response.put("roleIds", roleIds);
            response.put("message", "角色分配成功");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("为用户分配角色失败 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "分配角色失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/{userId}/roles")
    public ResponseEntity<?> getUserRoles(@PathVariable Long userId) {
        logger.info("获取用户角色 - 用户ID: {}", userId);
        
        try {
            Optional<User> userOpt = userRepository.findById(userId);
            
            if (!userOpt.isPresent()) {
                logger.warn("获取用户角色失败 - 未找到用户 ID: {}", userId);
                return ResponseEntity.notFound().build();
            }
            
            List<UserRole> userRoles = userRoleRepository.findByUserId(userId);
            List<Long> roleIds = userRoles.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());
            
            List<Role> roles = roleRepository.findAllById(roleIds);
            
            logger.info("获取用户角色成功 - 用户ID: {}, 角色数量: {}", userId, roles.size());
            
            Map<String, Object> response = new HashMap<>();
            response.put("userId", userId);
            response.put("roles", roles);
            response.put("roleIds", roleIds);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取用户角色失败 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取用户角色失败: " + e.getMessage()));
        }
    }
} 